using System;
using System.Linq;
using NHibernate;
using NHibernate.Linq;
using Caramel;

namespace Caramel.NHibernate
{
	public class NHibernateRepository<T> : IRepository<T> where T : class
	{
		public ISession Session 
		{
			get
			{
				if (UnitOfWork.Current == null)
				{
					throw new InvalidOperationException("No unit of work exists for the operation.");
				}

				if (!(UnitOfWork.Current is INHibernateUnitOfWork))
				{
					throw new InvalidOperationException(String.Format("Current unit of work does not implement {0}.", typeof(INHibernateUnitOfWork).Name));
				}

				return ((INHibernateUnitOfWork)UnitOfWork.Current).Session;
			}
		}

		#region IRepository<T> Members

		public T Get(object id)
		{
			return this.Session.Get<T>(id);
		}

		public void Save(T entity)
		{
			this.Session.SaveOrUpdate(entity);
		}

		public void Delete(T entity)
		{
			this.Session.Delete(entity);
		}

		public void DeleteAll()
		{
			this.Session.Delete(String.Format("from {0}", typeof(T).Name));
		}

		public IQueryable<T> All
		{
			get
			{
				return this.Session.Query<T>();
			}
		}

		#endregion
	}
}
